/*****************************************************************************
* File Name: mpu6500.h
*
* Version: 1.0
*
* Description:
* This file contains API for motion sensor
*
* Note:
* Define DISABLE_MOTION_SENSOR in platform.h to disable motion sensor module
*
* Owner: KMVP
*
* Related Document:
* SCB component datasheet
*
* Hardware Dependency:
* MPU6500 Datasheet
*
* Code Tested With:
* 1. PSoC Creator 3.1 
* 2. ARM GCC 4.8.4
******************************************************************************
* Copyright (2015), Cypress Semiconductor Corporation.
******************************************************************************
* This software is owned by Cypress Semiconductor Corporation (Cypress) and is
* protected by and subject to worldwide patent protection (United States and
* foreign), United States copyright laws and international treaty provisions.
* Cypress hereby grants to licensee a personal, non-exclusive, non-transferable
* license to copy, use, modify, create derivative works of, and compile the
* Cypress Source Code and derivative works for the sole purpose of creating
* custom software in support of licensee product to be used only in conjunction
* with a Cypress integrated circuit as specified in the applicable agreement.
* Any reproduction, modification, translation, compilation, or representation of
* this software except as specified above is prohibited without the express
* written permission of Cypress.
*
* Disclaimer: CYPRESS MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH
* REGARD TO THIS MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 
* Cypress reserves the right to make changes without further notice to the
* materials described herein. Cypress does not assume any liability arising out
* of the application or use of any product or circuit described herein. Cypress
* does not authorize its products for use as critical components in life-support
* systems where a malfunction or failure may reasonably be expected to result in
* significant injury to the user. The inclusion of Cypress' product in a life-
* support systems application implies that the manufacturer assumes all risk of
* such use and in doing so indemnifies Cypress against all charges. Use may be
* limited by and subject to the applicable Cypress software license agreement.
*****************************************************************************/
#ifndef _MPU6500_H_
#define _MPU6500_H_

#include "motion_sensor_hal.h"

/* Address of I2C slave is decide from input at AD0 pin of the chip*/
/* define the pin state below according to the hardware setting */
#define MPU6500_PIN_AD0_STATE                    0

#if(MPU6500_PIN_AD0_STATE == 0)
    #define MPU6500_I2C_SLAVE_ADDRESS             (0x68)
#else
    #define MPU6500_I2C_SLAVE_ADDRESS             (0x69)
#endif /* (MPU6500_PIN_AD0_STATE == 0) */

/* Register Address for Accerolometer in MPU6500 */
#define MPU6500_ACCEL_CONFIG_ADR                (0x1C)
#define MPU6500_MOT_THR_ADR                     (0x1F)
#define MPU6500_MOT_DUR_ADR                     (0x20)
#define MPU6500_INT_PIN_CFG_ADR                 (0x37)
#define MPU6500_INT_ENABLE_ADR                  (0x38)
#define MPU6500_INT_STATUS_ADR                  (0x3A)
#define MPU6500_ACCEL_XOUT_H_ADR                (0x3B)
#define MPU6500_ACCEL_XOUT_L_ADR                (0x3C)
#define MPU6500_ACCEL_YOUT_H_ADR                (0x3D)
#define MPU6500_ACCEL_YOUT_L_ADR                (0x3E)
#define MPU6500_ACCEL_ZOUT_H_ADR                (0x3F)
#define MPU6500_ACCEL_ZOUT_L_ADR                (0x40)

/* Register Address for Gyro in MPU6500 */
#define MPU6500_SMPLRT_DIV_ADR                  (0x19)
#define MPU6500_CONFIG_ADR                      (0x1A)
#define MPU6500_GYRO_CONFIG_ADR                 (0x1B)
#define MPU6500_GYRO_OUT_X_H_ADR                (0x43)
#define MPU6500_GYRO_OUT_X_L_ADR                (0x44)
#define MPU6500_GYRO_OUT_Y_H_ADR                (0x45)
#define MPU6500_GYRO_OUT_Y_L_ADR                (0x46)
#define MPU6500_GYRO_OUT_Z_H_ADR                (0x47)
#define MPU6500_GYRO_OUT_Z_L_ADR                (0x48)
#define MPU6500_USER_CONTROL_ADR                (0x6A)
#define MPU6500_PWR_MGMT_1_ADR                  (0x6B)
#define MPU6500_PWR_MGMT_2_ADR                  (0x6C)
#define MPU6500_WHOAMI_ADR                      (0x75)

/* USER_CTRL */
#define MPU6500_USER_CTRL_I2C_MST_EN            (0x20)

/* ACCEL_CONFIG */
#define MPU6500_ACCEL_CONFIG_AFSEL_FS2G         (0x00)
#define MPU6500_ACCEL_CONFIG_AFSEL_FS4G         (0x08)
#define MPU6500_ACCEL_CONFIG_AFSEL_FS8G         (0x10)
#define MPU6500_ACCEL_CONFIG_AFSEL_FS16G        (0x18)
#define MPU6500_ACCEL_CONFIG_HPF_RESET          (0x00)
#define MPU6500_ACCEL_CONFIG_HPF_0_63HZ         (0x04)
#define MPU6500_ACCEL_CONFIG_HPF_HOLD           (0x07)

/* INT_PIN_CFG */
#define MPU6500_INT_PIN_CFG_LATCH_INT_EN        (0x20)
#define MPU6500_INT_PIN_CFG_I2C_BYPASS_EN       (0x02)

/* INT_ENABLE */
#define MPU6500_INT_ENABLE_MOT_EN               (0x40)

/* CONFIG */
#define MPU6500_CONFIG_LPFILTER_256Hz           (0x00)          /** Outout Data Rate 256Hz but removed 8KHz internal sampling */
#define MPU6500_CONFIG_LPFILTER_98Hz            (0x02)          /** Outout Data Rate 98Hz */

/* GYRO_CONFIG */
#define MPU6500_GYRO_CONFIG_FULLSCALE_250       (0x00)          /** Full Scale +/-2000 dps */
#define MPU6500_GYRO_CONFIG_FULLSCALE_500       (0x08)          /** Full Scale +/-2000 dps */
#define MPU6500_GYRO_CONFIG_FULLSCALE_1000      (0x10)          /** Full Scale +/-2000 dps */
#define MPU6500_GYRO_CONFIG_FULLSCALE_2000      (0x18)          /** Full Scale +/-2000 dps */

/* PWR_MGMT_1 */
#define MPU6500_PWR_MGMT_1_INTERNALOSC          (0x00)         /** Use Internal oscillator */ 
#define MPU6500_PWR_MGMT_1_PLL_ZGYRREF          (0x03)         /** PLL with Z Gyro Reference */
#define MPU6500_PWR_MGMT_1_SLEEP                (0x40)
#define MPU6500_PWR_MGMT_1_CYCLE                (0x20)
#define MPU6500_PWR_MGMT_1_TEMP_DIS             (0x08)
#define MPU6500_PWR_MGMT_1_RESET                (0x80)

/* PWR_MGMT_2 */
#define MPU6500_PWR_MGMT_2_STBY_ZG              (0x01)
#define MPU6500_PWR_MGMT_2_STBY_YG              (0x02)
#define MPU6500_PWR_MGMT_2_STBY_XG              (0x04)
#define MPU6500_PWR_MGMT_2_STBY_ZA              (0x08)
#define MPU6500_PWR_MGMT_2_STBY_YA              (0x10)
#define MPU6500_PWR_MGMT_2_STBY_XA              (0x20)
#define MPU6500_PWR_MGMT_2_LP_WAKE_CTRL         (0xC0)

/* ACCEL_INTEL_CTR */
#define MPU6500_ACCEL_INTEL_CTRL_ADR            (0x69)
#define MPU6500_ACCEL_INTEL_EN                  (0x80)
#define MPU6500_ACCEL_INTEL_MODE                (0x40)

#define MPU6500_LP_ACCEL_ODR_ADR                (0x1E)

#define MPU6500_GYROSCOPE_SAMPLES               (0x6)
#define MPU6500_ACCELEROMETER_SAMPLES           (0x6)
#define MOTION_WAKEUP_THRESHOLD                 (0x08)

#ifndef DISABLE_MOTION_SENSOR

/* Initialize Gyroscope */
#define MPU6500_Reset()                         (MPU6500_WriteRegister(MPU6500_PWR_MGMT_1_ADR, MPU6500_PWR_MGMT_1_RESET));CyDelay(1)
/*****************************************************************************
* Function Name: MPU6500_Stop()
******************************************************************************
* Summary:
* This function is used to put MPU6500 ACC and GYRO in Power down 
*
* Parameters:
* None
*
* Return:
* None
*****************************************************************************/
void MPU6500_Stop(void);

/*****************************************************************************
* Function Name: MPU6500_Read_WhoAmI()
******************************************************************************
* Summary:
* This function is used to read the  WHOAMI Register
*
* Parameters:
* None
*
* Return:
* None
* 
* Note
* It is resposible of the Caller to send the valid pointer to this API
****************************************************************************/
void MPU6500_Read_WhoAmI(uint8 * data);

/*****************************************************************************
* Function Name: MPU6500_GYRO_GetSample()
******************************************************************************
* Summary:
* This function is used to Get X, Y and Z GYRO informations
*
* Parameters:
* int16 *bufferData
*
* Return:
* None
* 
* Note
* It is resposible of the Caller to send the valid pointer to this API
*****************************************************************************/
void MPU6500_GYRO_GetSample(int16_t * bufferData);

/*****************************************************************************
* Function Name: MPU6500_ACC_GetSample()
******************************************************************************
* Summary:
* This function is used to Read accelerometer samples
*
* Parameters:
* int16 *lAccValue - A table of 3 byte for assigning accelerometer sample
*
* Return:
* None
* 
* Note
* It is resposible of the Caller to send the valid pointer to this API
*****************************************************************************/
void MPU6500_ACC_GetSample(int16_t * lAccValue);

/*****************************************************************************
* Function Name: MPU6500_StopMotionDetection()
******************************************************************************
* Summary:
* This function is used to disable motion detection mode
*
* Parameters:
* None
*
* Return:
* None
*****************************************************************************/
void MPU6500_StopMotionDetection(void);

/*****************************************************************************
* Function Name: MPU6500_StartMotionDetection()
******************************************************************************
* Summary:
* This function is puts the Motion sensor in low power Motion Detect mode
* with INT pin configured as level interrupt
*
* Parameters:
* None
*
* Return:
* None
*****************************************************************************/
void MPU6500_StartMotionDetection(void);

/*****************************************************************************
* Function Name: MPU6500_GYRO_SetPowerDownMode()
******************************************************************************
* Summary:
* This function is used to put MPU6500 GYRO only in power down.
*
* Parameters:
* None
*
* Return:
* None
*****************************************************************************/
void MPU6500_GYRO_SetPowerDownMode(void);

/*****************************************************************************
* Function Name: MPU6500_ACC_SetPowerDownMode()
******************************************************************************
* Summary:
* This function is used to put MPU6500 ACC in Power down (Gyroscope is always already 
* powered down when this function is called)
*
* Parameters:
* None
*
* Return:
* None
*****************************************************************************/
void MPU6500_ACC_SetPowerDownMode(void);

/*****************************************************************************
* Function Name: MPU6500_Start()
******************************************************************************
* Summary:
* This function is used to Start gyroscope, accelerometer data sampling with
* a specific configuration.
*
* Parameters:
* None
*
* Return:
* None
*****************************************************************************/
void MPU6500_Start(void); 

/*****************************************************************************
* Function Name: MPU6500_ReadMultiRegister()
******************************************************************************
* Summary:
* This function reads MPU6500 register with consecutive address using I2C component 
*
* Parameters:
* uint8 address - register address inside the sensor chip to be written
* uint8 data    - pointer of the buffer to whre read data should be stored
* uint8 len     - number of registers to be read
*
* Return:
* None
*****************************************************************************/
void MPU6500_ReadMultiRegister(uint8 address, uint8 *data, uint8 len);

/*****************************************************************************
* Function Name: MPU6500_WriteRegister()
******************************************************************************
* Summary:
* This function writes the MPU6500 register using I2C component
*
* Parameters:
* address : register address inside the sensor chip to be written
* data : 8 bit data to be written
*
* Return:
* None
*****************************************************************************/
void MPU6500_WriteRegister(uint8 address, uint8 data);

/*****************************************************************************
* Function Name: MPU6500_ReadRegister()
******************************************************************************
* Summary:
* This function reads the MPU6500 register using I2C component
*
* Parameters:
* address : register address inside the sensor chip to be written
*
* Return:
* Data read from the sensor
*****************************************************************************/
uint8 MPU6500_ReadRegister(uint8 address);

#else

#define MPU6500_ReadRegister(address)
#define MPU6500_WriteRegister(address,data)
#define MPU6500_ReadMultiRegister(address,data,len)
#define MPU6500_Start() 
#define MPU6500_ACC_SetPowerDownMode()
#define MPU6500_GYRO_SetPowerDownMode()
#define MPU6500_StartMotionDetection()
#define MPU6500_StopMotionDetection()
#define MPU6500_GYRO_GetSample( bufferData)
#define MPU6500_ACC_GetSample(lAccValue)
#define MPU6500_Stop()
#define MPU6500_Reset()

#endif /* # DISABLE_MOTION_SENSOR */

#endif /* _MPU6500_H_ */
